package io.renren.utils;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
public class HttpClientUtil {
    private static final RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(60000) // 60s
            .setConnectTimeout(10000) // 10s
            .setConnectionRequestTimeout(10000) // 10s
            .build();


    public static String sendHttpPost(String httpUrl, String body, Map<String, String> header) {
        HttpPost httpPost = new HttpPost(httpUrl);
        try {
            if (StringUtils.isNotEmpty(body)) {
                StringEntity stringEntity = new StringEntity(body, "UTF-8");
                stringEntity.setContentType("application/json");
                httpPost.setEntity(stringEntity);
            }
            if (CollectionUtil.isNotEmpty(header)) {
                for (Map.Entry<String, String> entry : header.entrySet()) {
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
        } catch (Exception e) {
            log.error("httpUrl is {}, body is {}, header is {}, error: ", httpUrl, body, header.toString(), e);
        }
        return sendHttpPost(httpPost);
    }

    private static String sendHttpPost(HttpPost httpPost) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        String responseContent = "";
        try {
            httpClient = HttpClients.createDefault();
            httpPost.setConfig(requestConfig);
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            log.error("sendHttpPost exception ", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                log.error("close client exception ", e);
            }
        }
        return responseContent;
    }


    public static String sendHttpPut(String httpUrl, String body, Map<String, String> header) {
        HttpPut httpPut = new HttpPut(httpUrl);
        try {
            if (StringUtils.isNotEmpty(body)) {
                StringEntity stringEntity = new StringEntity(body, "UTF-8");
                stringEntity.setContentType("application/json");
                httpPut.setEntity(stringEntity);
            }
            if (CollectionUtil.isNotEmpty(header)) {
                for (Map.Entry<String, String> entry : header.entrySet()) {
                    httpPut.addHeader(entry.getKey(), entry.getValue());
                }
            }
        } catch (Exception e) {
            log.error("httpUrl is {}, body is {}, header is {}, error: ", httpUrl, body, header.toString(), e);
        }
        return sendHttpPut(httpPut);
    }

    private static String sendHttpPut(HttpPut httpPut) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        String responseContent = "";
        try {
            httpClient = HttpClients.createDefault();
            httpPut.setConfig(requestConfig);
            response = httpClient.execute(httpPut);
            HttpEntity entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            log.error("sendHttpPut exception ", e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                log.error("close client exception ", e);
            }
        }
        return responseContent;
    }


    public static String sendHttpGet(String httpUrl, Map<String, String> params, Map<String, String> header) {
        List<BasicNameValuePair> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(params)) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            String paramStr = "";
            try {
                paramStr = EntityUtils.toString(new UrlEncodedFormEntity(list, Consts.UTF_8));
            } catch (IOException e) {
                log.error("params NameValuePair to String exception: ", e);
            }
            if (StringUtils.isNotEmpty(paramStr)) {
                httpUrl = httpUrl + "?" + paramStr;
            }
        }
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
        if (CollectionUtil.isNotEmpty(header)) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                httpGet.addHeader(entry.getKey(), entry.getValue());
            }
        }
        return sendHttpGet(httpGet);
    }

    public static String sendHttpGet(String httpUrl) {
        HttpGet httpGet = new HttpGet(httpUrl);// 创建get请求
        return sendHttpGet(httpGet);
    }

    private static String sendHttpGet(HttpGet httpGet) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            httpClient = HttpClients.createDefault();
            httpGet.setConfig(requestConfig);
            response = httpClient.execute(httpGet);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            log.error("sendHttpGet error, httpUrl={}, error: ", httpGet.getURI().getPath(), e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                log.error("close resources error", e);
            }
        }
        if (StringUtils.isEmpty(responseContent)) {
            log.warn("responseContent is null");
        }
        return responseContent;
    }

    public static String sendHttpDelete(String httpUrl, Map<String, String> header) {
        HttpDelete httpDelete = new HttpDelete(httpUrl);
        if (header != null && !header.isEmpty()) {
            for (Map.Entry<String, String> entry : header.entrySet()) {
                httpDelete.addHeader(entry.getKey(), entry.getValue());
            }
        }
        return sendHttpDelete(httpDelete);
    }

    private static String sendHttpDelete(HttpDelete httpDelete) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse response = null;
        HttpEntity entity = null;
        String responseContent = null;
        try {
            httpClient = HttpClients.createDefault();
            httpDelete.setConfig(requestConfig);
            response = httpClient.execute(httpDelete);
            entity = response.getEntity();
            responseContent = EntityUtils.toString(entity, "UTF-8");
        } catch (Exception e) {
            log.error("sendHttpDelete error, httpUrl={}, error: ", httpDelete.getURI().getPath(), e);
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                log.error("close resources error", e);
            }
        }
        if (StringUtils.isEmpty(responseContent)) {
            log.warn("responseContent is null");
        }
        return responseContent;
    }
}
